﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenExpressApp.MetaAttribute;
using Csla.Wpf;
using OpenExpressApp.Command;
using Csla.Core;
using System.ComponentModel;
using System.Windows;
using OpenExpressApp.Template;
using OpenExpressApp.Types;
using Csla;
using OpenExpressApp.WPF.Controls;
using System.Collections.ObjectModel;
using log4net;
using System.Collections;
using OpenExpressApp.MetaModel;
using Avalon.Windows.Controls;
using OpenExpressApp.WPF.Templete;
using OpenExpressApp.Module;
using OpenExpressApp.Module.WPF;
using System.Windows.Controls;
using Ricciolo.Controls;
using System.Reflection;
using System.Windows.Markup;
using System.Diagnostics;
using AvalonDock;
using OpenExpressApp.Module.WPF.Editors;
using OpenExpressApp.Module.WPF.Command;

namespace OpenExpressApp.WPF.Command
{
    public abstract class OrderedTreeListViewCommand : WPFListViewCommand
    {
        /// <summary>
        /// 是树的视图，则可以显示
        /// </summary>
        /// <param name="view"></param>
        /// <returns></returns>
        public override bool CanVisible(ListObjectView view)
        {
            if (view == null)
            {
                return false;
            }

            var boType = view.BOType;
            return view.InOrder &&
                typeof(ITreeNode).IsAssignableFrom(boType) &&
                typeof(IOrderedObject).IsAssignableFrom(boType);
        }
        public override bool CanExecute(ListObjectView view)
        {
            return this.SelectedRightType(view) &&
                view.CurrentObject is IOrderedObject &&
                view.CurrentObject is ITreeNode;
        }
    }

    #region 展开、折叠

    [Command(CommandNames.ExpandAll, ImageName = "ExpandAll.bmp", Label = "全部展开", ToolTip = "全部展开")]
    public class ExpandAllCommand : WPFListViewCommand
    {
        public override bool CanVisible(ListObjectView view)
        {
            return view != null && view.IsShowingTree;
        }
        public override void Execute(ListObjectView view)
        {
            (view.Control as MultiObjectTreeView).ExpandAll();
        }
    }

    [Command(CommandNames.CollapseAll, ImageName = "CollapseAll.bmp", Label = "全部折叠", ToolTip = "全部折叠")]
    public class CollapseAllCommand : WPFListViewCommand
    {
        public override bool CanVisible(ListObjectView view)
        {
            return view != null && view.IsShowingTree;
        }
        public override void Execute(ListObjectView view)
        {
            (view.Control as MultiObjectTreeView).CollapseAll();
        }
    }

    #endregion

    #region 上、下移

    public abstract class MoveCommand : OrderedTreeListViewCommand
    {
        protected abstract bool MoveUp { get; }
        public override bool CanExecute(ListObjectView view)
        {
            if (base.CanExecute(view))
            {
                var node = (view.CurrentObject as ITreeNode);

                var list = view.Data as ITreeNodeCollection;
                if (list == null)
                {
                    return false;
                }
                var checkNode = list.FindNodeAtSameLevel(node, this.MoveUp);
                return checkNode != null;
            }
            return false;
        }
        public override void Execute(ListObjectView view)
        {
            var list = view.Data as IOrderedTreeNodeCollection;
            if (list == null) throw new ArgumentNullException("list");

            ITreeNode currentNode = view.CurrentObject as ITreeNode;

            list.MoveNode(currentNode as IOrderedObject, this.MoveUp);

            #region 更新控件

            //如果是树的根节点
            var treeViewControl = view.Control as MultiObjectTreeView;
            if (null == currentNode.ParentNode)
            {
                var items = treeViewControl.Roots;
                int distance = this.MoveUp ? -1 : 1;
                var currentObj = currentNode as BusinessBase;
                int index = items.IndexOf(currentObj);
                items.Move(index, index + distance);
            }
            else
            {
                treeViewControl.Expand(currentNode.ParentNode as BusinessBase, false);
            }

            #endregion

            view.CurrentObject = currentNode;
        }
    }

    [Command(CommandNames.MoveDown, ImageName = "MoveDown.bmp", Label = "下移", ToolTip = "下移")]
    public class MoveDownCommand : MoveCommand
    {
        protected override bool MoveUp
        {
            get { return false; }
        }
    }

    [Command(CommandNames.MoveUp, ImageName = "MoveUp.bmp", Label = "上移", ToolTip = "上移")]
    public class MoveUpCommand : MoveCommand
    {
        protected override bool MoveUp
        {
            get { return true; }
        }
    }

    #endregion

    #region 升、降级

    [Command(CommandNames.LevelUp, ImageName = "LevelUp.bmp", Label = "升级", ToolTip = "升级")]
    public class LevelUpCommand : OrderedTreeListViewCommand
    {
        public override bool CanExecute(ListObjectView view)
        {
            return base.CanExecute(view) &&
                (view.CurrentObject as ITreeNode).ParentNode != null;
        }
        public override void Execute(ListObjectView view)
        {
            var list = view.Data as IOrderedTreeNodeCollection;
            if (list == null) throw new ArgumentNullException("list");

            var currentObject = view.CurrentObject as BusinessBase;
            var currentNode = currentObject as ITreeNode;
            var oldParent = currentNode.ParentNode as BusinessBase;

            //在结构中更改数据
            list.ChangeNodeLevel(currentNode, true);

            #region 更新视图

            //删除旧节点
            var treeControl = view.Control as MultiObjectTreeView;
            treeControl.RemoveNode(currentNode as BusinessBase);

            //如果变成了根节点，需要手动更新视图
            if (null == currentNode.ParentNode)
            {
                var control = view.Control as MultiObjectTreeView;
                var items = control.Roots;
                var newViewIndex = items.IndexOf(oldParent) + 1;
                items.Insert(newViewIndex, currentObject);
            }

            #endregion

            view.CurrentObject = currentNode;
        }
    }

    [Command(CommandNames.LevelDown, ImageName = "LevelDown.bmp", Label = "降级", ToolTip = "降级")]
    public class LevelDownCommand : OrderedTreeListViewCommand
    {
        public override bool CanExecute(ListObjectView view)
        {
            if (base.CanExecute(view))
            {
                var list = view.Data as ITreeNodeCollection;
                if (list == null)
                {
                    return false;
                }
                var preNode = list.FindNodeAtSameLevel(view.CurrentObject as ITreeNode, true);
                return preNode != null;
            }
            return false;
        }
        public override void Execute(ListObjectView view)
        {
            var list = view.Data as IOrderedTreeNodeCollection;
            if (list == null) throw new ArgumentNullException("list");

            ITreeNode currentNode = view.CurrentObject as ITreeNode;

            list.ChangeNodeLevel(currentNode, false);

            //移除控件中的老节点。
            var treeControl = view.Control as MultiObjectTreeView;
            treeControl.RemoveNode(currentNode as BusinessBase);

            view.CurrentObject = currentNode;
        }
    }

    #endregion

    #region 前插、后插、添加子

    public abstract class InsertCommand : OrderedTreeListViewCommand
    {
        protected virtual bool InsertBefore
        {
            get
            {
                return true;
            }
        }
        protected virtual bool InsertAsChild
        {
            get
            {
                return false;
            }
        }

        public override bool CanExecute(ListObjectView view)
        {
            if (base.CanExecute(view))
            {
                var bindingList = view.Data as IBindingList;
                if (bindingList != null && bindingList.AllowNew)
                {
                    var list = bindingList as ITreeNodeCollection;
                    if (list == null)
                    {
                        return false;
                    }

                    var naviView = view.NavigateQueryView;
                    if (naviView != null)
                    {
                        //如果有导航面板，则必须先给导航值赋值
                        foreach (var naviProperty in naviView.NavigateProperties)
                        {
                            if (naviProperty.IsEntityId)
                            {
                                var pName = naviProperty.EntityProperty;
                                var value = naviView.CurrentObject.GetPropertyValue(pName);
                                if (value == null)
                                {
                                    return false;
                                }
                            }
                        }
                    }

                    return true;
                }
            }
            return false;
        }
        public override void Execute(ListObjectView view)
        {
            var list = view.Data as IOrderedTreeNodeCollection;
            if (list == null) throw new ArgumentNullException("list");

            var treeView = view.Control as MultiObjectTreeView;
            var currentObject = view.CurrentObject as BusinessBase;
            var currentNode = currentObject as ITreeNode;

            //插入为孩子，需要先打开父亲节点
            if (this.InsertAsChild)
            {
                var currentItem = treeView.GetItemByData(currentObject);
                currentItem.IsExpanded = true;
            }

            //建立新的对象
            var newObject = list.CreateNode(currentNode, this.InsertAsChild, this.InsertBefore) as BusinessBase;
            var newNode = newObject as ITreeNode;

            #region 设置新对象的一些属性值

            //添加记录时把导航关联值加入到当前记录中
            var navigateView = view.NavigateQueryView;
            if (navigateView != null)
            {
                navigateView.SetReferenceEntity(newObject);
            }

            //细表增加时自动添加外键
            if (null != view.Parent)
            {
                newObject.SetPropertyValue(view.GetKeyToParentView(), view.Parent.CurrentID);
                newObject.SetPropertyValue(view.GetKeyObjToParentView(), view.Parent.CurrentObject);
            }

            #endregion

            #region 构造树的父子关系，刷新视图

            //如果是树形，同级新增
            //如果没有选中，或者选中的是根节点
            if (newNode.ParentNode == null)
            {
                var items = treeView.Roots;
                if (currentObject != null)
                {
                    var currentIndex = items.IndexOf(currentObject);
                    items.Insert(this.InsertBefore ? currentIndex : currentIndex + 1, newObject);
                }
                else
                {
                    items.Add(newObject);
                }
                //treeView.ItemsSource = view.Data as IBindingList;
            }

            #endregion

            view.CurrentObject = newObject;
        }
    }

    [Command(CommandNames.InsertBefore, Label = "前插", ToolTip = "前插")]
    public class InsertBeforeCommand : InsertCommand { }

    [Command(CommandNames.InsertFollow, Label = "后插", ToolTip = "后插")]
    public class InsertFollowCommand : InsertCommand
    {
        protected override bool InsertBefore
        {
            get { return false; }
        }
    }

    [Command(CommandNames.AddChild, ImageName = "AddChild.bmp", Label = "添加子", ToolTip = "添加子记录")]
    public class AddChildCommand : InsertCommand
    {
        protected override bool InsertAsChild
        {
            get
            {
                return true;
            }
        }
    }

    #endregion
}